#ifndef SWANLINK_FINANCE_KEYBOARD_SERVICES_ADAPTOR_SNK008A_INCLUDE_SNK_ADAPTOR_H
#define SWANLINK_FINANCE_KEYBOARD_SERVICES_ADAPTOR_SNK008A_INCLUDE_SNK_ADAPTOR_H

#include <string>
#include <pthread.h>
#include <mutex>

#include "XZ_F31_API_LINUX.h"
#include "ikeyboardadaptor.h"
#include "plugin.h"

namespace SwanLink {
namespace Finance {

class SNK008A_Adaptor : public iKeyboard_Adaptor
{
 public:
    SNK008A_Adaptor();
    virtual ~SNK008A_Adaptor();
    virtual int Open(const Transport &tran);
    virtual int Close();
    virtual bool IsOpen();
    virtual int Reset();
    virtual int GetStatus(int module, char *err);
    virtual bool IsSM4Enabled();

    /*
     * 获取密码键盘序列号
     */
    virtual int GetSN(char sn[], int& len);

    /*
     * 计算MAC
     */
    virtual int CalculateMAC(const KeyInfo& key, char plain[], int len, char enc_data[], int &enc_len);

    /*
     * 加密数据
     */
    virtual int EncryptData(const KeyInfo& key, char plain[], int len, char enc_data[], int &len_enc);

    /*
     * 设置PIN的长度限制
     */
    virtual int SetPINLength(int minLen, int maxLen);

    /*
     * 设置明文密文模式
     */
    virtual int SetTextMode(TextMode mode);

    /*
     * 清空文本
     */
    virtual void ClearTextMode();
    /**
     * 加载主密钥
     */
    virtual int LoadMasterKey(KeyID masterKeyID, unsigned char *KeyValue);

    /*
     * 清空文本
     */
    virtual int LoadUserKey(KeyID masterKeyID, userKeyType user_Key_Type, unsigned char *KeyValue);

    /*
     * 更新密钥
     */
    virtual int UpdateMasterKey(KeyID masterKeyID, unsigned char *KeyValue);
    /*
     * 更新用户密钥
     */
    virtual int UpdateUserKey(KeyID masterKeyID, userKeyType user_Key_Type, unsigned char *KeyValue);

    /*
     * 删除用户密钥
     */
    virtual int DeleteUserKey(KeyID masterKeyID, userKeyType user_Key_Type);

    /*
     * 监听
     */
    virtual void ListenForPin(PinListener* listener, int timeout);

    void OnCharProcess(int code, char ch);
    void OnFailed(int code, const std::string &err);
    void OnResult(char *buf, int len);
    void ListenForRead();
    static void* ListenForPinThread(void *arg) {
      SNK008A_Adaptor *adaptor = static_cast<SNK008A_Adaptor*>(arg);
      printf("adaptor = %p\n", adaptor);
      adaptor->ListenForRead();
      return NULL;
    }
 private:
    int m_iFd;
    int m_iStatus = -1;
    bool flag = false;
    int m_timeout;
    int m_mode = 1;
    int keybuf_len = 0;
    char keybuf[256] = {0};
    std::mutex  pin_mutex;
    pthread_t  pin_thread_id;
    PinListener* pinListener{nullptr};
};
} // namespace Finance
} // namespace SwanLink
#endif // SWANLINK_FINANCE_KEYBOARD_SERVICES_ADAPTOR_SNK008A_INCLUDE_SNK_ADAPTOR_H
